package concurrency_design_model

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"math/rand"
	"os"
	"sort"
	"strconv"
	"strings"
	"time"
)

const (
	FilePath = "C:\\Users\\马军\\Desktop\\goland-workspace\\go_second_study\\concurrency_design_model\\data\\"
	FileNum  = 10
)

func main() {
	writerFinishChan := make(chan string, FileNum)
	SortExit := make(chan int, FileNum)

	//开启10个协程完成文件的写操作
	for i := 0; i < FileNum; i++ {
		go writerDataFile(writerFinishChan, FilePath+"data"+strconv.Itoa(i)+".txt", i)
	}

	//开启10个协程来读取文件进行排序
	for i := 0; i < FileNum; i++ {
		go sortAndWrite(writerFinishChan, SortExit)
	}

	for {
		_, ok := <-SortExit
		if !ok {
			fmt.Println("读取和写入文件完成。。")
			close(writerFinishChan)
			break
		} else {
			fmt.Println("等待完成。。。。。")
		}
	}
}

//写入数据
func writerDataFile(writerExit chan string, filePath string, fileNum int) {
	fmt.Println("开始写入文件，路径=", filePath)
	rand.Seed(time.Now().UnixNano())
	//标记这是第几个文件
	writeFile(filePath, strconv.Itoa(fileNum)+";")
	str := ""
	for i := 0; i < 1000; i++ {
		num := rand.Intn(1000) + 1
		if i == 999 {
			str += strconv.Itoa(num)
		} else {
			str += strconv.Itoa(num) + ","
		}
	}
	writeFile(filePath, str)
	writerExit <- filePath
}

//读取文件中的数据
func sortAndWrite(writerExit chan string, SortExit chan int) {
	select {
	case filePath := <-writerExit:
		//写完成
		fmt.Println("写完成，开始读取文件。。。")
		strs := readFile(filePath)
		fmt.Printf("读取数据=%v\n", strs)
		split := strings.Split(strs, ",")
		var nums = make([]int, 1000)
		for i, v := range split {
			atoi, _ := strconv.Atoi(v)
			nums[i] = atoi
		}
		//排序
		sort.Ints(nums)
	}
	SortExit <- 1
}

//写文件
func writeFile(filePath string, content string) {
	file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		fmt.Println("操作文件失败", err)
	}

	defer file.Close()

	writer := bufio.NewWriter(file)
	_, err = writer.WriteString(content)
	if err != nil {
		return
	}

	err = writer.Flush()
	if err != nil {
		fmt.Println("flush失败")
	}
}

//读文件
func readFile(filePath string) string {
	open, err := os.Open(filePath)
	if err != nil {
		log.Fatalln("读取文件错误，路径=", filePath)
	}

	defer open.Close()

	str := ""
	reader := bufio.NewReader(open)
	for {
		readString, err := reader.ReadString('\n')
		if err != nil {
			if err == io.EOF {
				fmt.Println("读取结束")
				break
			}
			fmt.Println("读取文件错误", err)
			continue
		}

		str = str + readString
	}

	return str
}
